package com.xc.stock.domain.basic.service;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ag.exception.SysTipsException;
import com.ag.utils.AgAssert;
import com.ag.utils.CollectionUtils;
import com.ag.utils.SysConstant.YesNoEnum;
import com.google.common.collect.Lists;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.xc.stock.constant.AccountType;
import com.xc.stock.constant.RoleEnum;
import com.xc.stock.domain.basic.entity.TradeAcc;
import com.xc.stock.domain.basic.factory.TradeAccFactory;
import com.xc.stock.domain.basic.repository.TradeAccRepository;
import com.xc.stock.dto.model.DestInfo;
import com.xc.stock.infrastructure.db.po.QTradeAccPO;
import com.xc.stock.utils.SpringUtils;

import lombok.RequiredArgsConstructor;

/**
 * TradeAccService
 *
 * @author rplees
 * @email rplees.i.ly@gmail.com
 * @created 2022/08/12
 */
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class TradeAccService {
	final TradeAccRepository repository;
	final TradeAccFactory factory;
	static final QTradeAccPO q = QTradeAccPO.tradeAccPO;
	public Map<Integer, TradeAcc> findTradeAccMap(List<DestInfo> dest, AccountType type) {
		return getTradeAcc(dest, type)
				.stream()
				.collect(Collectors.toMap(val -> val.getDestId(), val -> val, (o, v) -> o));
	}
	
	public List<TradeAcc> getTradeAcc(List<DestInfo> dest, AccountType type) {
		if(CollectionUtils.isEmpty(dest)) {
			return Lists.newArrayList();
		}
		
		boolean count = dest.stream().map(val -> val.getRe()).count() == 1;
		AgAssert.isTrue(count, SysTipsException.class, "只能一种角色");
		RoleEnum re = dest.get(0).getRe();
		List<Integer> ids = Lists.transform(dest, val -> val.idInt());
		BooleanExpression where = q.destId.in(ids)
			.and(q.role.eq(re.code()))
			.and(q.type.eq(type.code()))
			.and(q.fakeFlag.eq(YesNoEnum.NO.v()));
		return repository.findAll(where);
	}
	
	public TradeAcc getTradeAcc(DestInfo dest, AccountType type) {
		Map<Integer, TradeAcc> map = findTradeAccMap(Lists.newArrayList(dest), type);
		return map.get(dest.idInt());
	}

	public TradeAcc createTradeAcc(DestInfo destInfo, AccountType type) {
		TradeAcc acc = factory.from(destInfo, type);
		repository.save(acc);
		return acc;
	}
	
	public TradeAccRepository repository() {
		return repository;
	}

	public static TradeAccService of() {
		return SpringUtils.getBean(TradeAccService.class);
	}
}
